package JVM工作区;

import java.awt.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;

/**
 * @ClassName: TestClassLoader
 * @Author: AllenSun
 * @Date: 2022/3/29 下午9:06
 */
public class TestClassLoader {
    public static void main(String[] args) {
        //使用反射获取类的对象
        Class mainClass = TestClassLoader.class;
        //类的对象调用方法获得该Class对象的类装载器
        ClassLoader classLoader = mainClass.getClassLoader();
        System.out.println("类加载器的名称："+classLoader.toString());
        //类加载器的名称：sun.misc.Launcher$AppClassLoader@18b4aac2
        //类是AppClassLoader，路径是sun.misc.Launcher下

        ClassLoader parentLoader = classLoader.getParent();
        System.out.println("类加载器classLoader的父加载器的名称："+parentLoader.toString());
        //类加载器的父加载器的名称：sun.misc.Launcher$ExtClassLoader@29453f44

        URL[] mUrlsExt = ((URLClassLoader)parentLoader).getURLs();
        for (URL url:mUrlsExt) {
            System.out.println(url);
            //ExtClassLoader的加载路径加载的是jre/lib/ext/目录下的扩展包
        }

        ClassLoader parentLoader2 = parentLoader.getParent();
        System.out.println("类加载器parentLoader的父加载器的名称："+parentLoader2);
        //输出为null，因为BootstrapClassLoader是C++实现的，所以它没有对应的Java类

        try {
            Class launcheClass = Class.forName("sun.misc.Launcher");
            Method methodGetClassPath = launcheClass.getDeclaredMethod("getBootstrapClassPath",null);
            if(null!=methodGetClassPath){
                methodGetClassPath.setAccessible(true);
                Object object = methodGetClassPath.invoke(null,null);
                if(null!=object){
                    Method methodGetUrls = object.getClass().getDeclaredMethod("getURLs",null);
                    if(null!=methodGetUrls){
                        methodGetUrls.setAccessible(true);
                        URL[] mUrlBoot = (URL[]) methodGetUrls.invoke(object,null);
                        print(mUrlBoot);
                        //BootstrapClassLoader的加载路径是jre/lib目录，加载的是jre/lib/目录下的核心库
                    }
                }
            }
        } catch (ClassNotFoundException | NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }


        Class listClass = List.class;
        ClassLoader listLoader = listClass.getClassLoader();
        System.out.println("List类的加载器的名字："+listLoader.toString());
        //List的classLoader为空，因为像List是属于jdk中的东西，而jdk其实是放在一个rt.jar包中
        //jre/lib/目录下，通过上面说的，jre/lib/这个目录的jar包应该是由BootstrapClassLoader负责加载的，而这个BootstrapClassLoader类加载器是C++实现的，没有对应的Java类，所以打印出的结果为null。

    }


    public static void print(URL[] urls) {
        for (URL url:urls) {
            System.out.println(url);
        }
    }

}
